package org.flexthinker.binding.conversion.support
{
    import org.flexthinker.binding.conversion.Converter;

    /**
     * Default implementation for <code>Converter</code> interface.
     * Offers an easy hook in the constructor to define the 2 functions used to
     * convert the given value into another value.
     *
     * <p>
     *     By default this class offers a few basic convertion implementations
     *     between String, Int, Number and Boolean values, using Explicit conversions
     *     offered by ActionScript 3.0.
     *
     *     For more information about Explicit conversion, you can go to this
     *     <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=03_Language_and_Syntax_12.html">link</a>
     * </p>
     *
     * @see org.flexthinker.binding.conversion.Converter
     * @see org.flexthinker.binding.value.support.TypeConverter
     */
    public class PropertyConverter implements Converter
    {
        private var convertToClosure:Function;
        private var convertFromClosure:Function;

        public static const STRING_TO_INT_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToInt(value:String):int
                {
                    return int(value);
                },
                function convertToString(value:int):String
                {
                    return value.toString();
                }
                );

        public static const STRING_TO_NUMBER_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToNumber(value:String):Number
                {
                    return Number(value);
                },
                function convertToString(value:Number):String
                {
                    return value.toString();
                }
                );

        public static const STRING_TO_BOOLEAN_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToBoolean(value:String):Boolean
                {
                    return value.toLowerCase() == "true";
                },
                function convertToString(value:Boolean):String
                {
                    return value.toString();
                }
                );

        public static const INT_TO_STRING_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToString(value:int):String
                {
                   return value.toString();
                },
                function convertToInt(value:String):int
                {
                   return int(value);
                }
                );

        public static const NUMBER_TO_STRING_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToString(value:Number):String
                {
                    return value.toString();
                },
                function convertToNumber(value:String):Number
                {
                    return Number(value);
                }
                );
        public static const BOOLEAN_TO_STRING_CONVERTER:PropertyConverter
                = new PropertyConverter(
                function convertToString(value:Boolean):String
                {
                    return value.toString();
                },
                function convertToBoolean(value:String):Boolean
                {
                    return value.toLowerCase() == "true";
                }
                );


        public function PropertyConverter(convertToClosure:Function, convertFromClosure:Function):void
        {
            this.convertToClosure = convertToClosure;
            this.convertFromClosure = convertFromClosure;
        }


        public function convertForward(value:*):*
        {
            return convertToClosure.call(this, value);
        }

        public function convertReverse(value:*):*
        {
            return convertFromClosure.call(this, value);
        }
    }
}
